<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <title>promise作用延申</title>
  </head>
  <body>
    <script>
      // 回调地狱问题：
      // 当代码中存在多个异步任务(ajax、本地文件读写、数据库操作)，且异步任务之间有顺序要求，如何解决这个问题。
      // 一般都是通过嵌套实现多个异步任务按顺序执行的问题。虽然保证了任务的先后顺序，但是牺牲了代码的可读性。

      // 举例：如果多个ajax异步任务没有顺序要求，请求和请求之间没有任何联系，那么多个任务不用嵌套。
      //#region 无顺序任务
      // ip定位的
      /*
      axios.get("https://restapi.amap.com/v3/ip?key=e45ba07980d4a0817d2edeba0de23add").then((data) => console.log(data))
      // 获取优惠券
      axios.get("https://apif.java.crmeb.net/api/front/index").then((data) => console.log(data))
      */
      //#endregion

      // 举例：有顺序要求，请求和请求的数据之间存在联系，请求必须按顺序执行。
      // 嵌套的异步任务层次越来越深，代码结构越来越复杂，代码可读性不好，维护性不好。这种代码形式就是回调地狱。
      // 1. 先ip定位，获取城市
      //#region 回调地狱示例
      /*
      axios
        .get(
          "https://restapi.amap.com/v3/ip?key=e45ba07980d4a0817d2edeba0de23add"
        )
        .then((data) => {
          // 2. 根据城市查询天气
          aixos
            .get(
              `https://restapi.amap.com/v3/weather/weatherInfo?key=e45ba07980d4a0817d2edeba0de23add&city=${cityname}&extensions=all`
            )
            .then((data) => {
              // 3. 根据天气，推荐用户是否出行
              aixos
                .get(
                  `https://restapi.amap.com/v3/weather/weatherInfo?key=e45ba07980d4a0817d2edeba0de23add&city=${cityname}&extensions=all`
                )
                .then((data) => {
                  console.log(data)
                  aixos
                    .get(
                      `https://restapi.amap.com/v3/weather/weatherInfo?key=e45ba07980d4a0817d2edeba0de23add&city=${cityname}&extensions=all`
                    )
                    .then((data) => {
                      console.log(data)
                      aixos
                        .get(
                          `https://restapi.amap.com/v3/weather/weatherInfo?key=e45ba07980d4a0817d2edeba0de23add&city=${cityname}&extensions=all`
                        )
                        .then((data) => {
                          console.log(data)
                        })
                    })
                })
            })
        })
        */
      //#endregion

      function request(url) {
        return new Promise((resolve, reject) => {
          axios({
            url,
          })
            .then(({ data }) => {
              resolve(data)
            })
            .catch(() => {
              reject("请求失败")
            })
        })
      }

      // 1. ip定位城市
      request(
        "https://restapi.amap.com/v3/ip?key=e45ba07980d4a0817d2edeba0de23add"
      )
        .then((cityinfo) => {
          console.log(cityinfo)
          // 注意：在第一个.then内部，通过return 返回下一个要发送的请求任务，其实return的就是第二个promise任务了
          // 2. 根据城市查询天气
          return request(
            `https://restapi.amap.com/v3/weather/weatherInfo?key=e45ba07980d4a0817d2edeba0de23add&city=${cityinfo.city}&extensions=all`
          )
        })
        .then((weather) => {
          console.log(weather)
          // 注意：在第二个.then内部，通过return返回下一个promise请求任务
          // 3. 根据天气查询出行建议
          return request("https://restapi.amap.com/v3/weather/weatherInfo")
        })
        .then((suggest) => {
          // 注意：在第三个.then内部，通过return返回下一个promise请求任务
          // 4. 根据出行建议查询出行时间
          return request("https://restapi.amap.com/v3/weather/weatherInfo")
        })
        .then((data) => {
          console.log(data)
        })

      // 这种解决方案还不是解决回调地狱的最终形态(解决方案)，最终解决方案是async+await，会让代码更简洁，优雅，可读性会更好。

      // 问题：
      // 1. 什么是回调地狱？形成的原因是什么？
      // 2. 怎么解决回调地狱？
    </script>
  </body>
</html>
